﻿using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using PPI.Client.Logic.Upload;
using PPI.Entities.Enumerator;

namespace PPI
{
    public partial class frmImagesFixer : frmBase
    {
        #region - Private properties -

        private LDistributionImageRecovery recoveryInstance;
        private Thread processThread;

        #endregion

        #region - Constructor -

        public frmImagesFixer()
        {
            InitializeComponent();
        }

        #endregion

        #region - Event handlers -

        private void frmImagesFixer_Load(object sender, EventArgs e)
        {
            try
            {
                LoadMobileDatabaseFiles();
                SetupRecoveryInstance();
            }
            catch(Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }


        private void btnStart_Click(object sender, EventArgs e)
        {
            if (lvMobileFiles.CheckedItems.Count == 0)
            {
                MessageBox.Show("No files selected.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            var arrayFilesSelected = new ArrayList();

            foreach (ListViewItem fileSelected in lvMobileFiles.CheckedItems) 
                arrayFilesSelected.Add(fileSelected.Tag);

            pbDataBase.Maximum = arrayFilesSelected.Count;
            btnStart.Enabled = false;
            recoveryInstance.FilesToCheck = (FileInfo[]) arrayFilesSelected.ToArray(typeof (FileInfo));
            processThread = new Thread(StartProcess); 
            processThread.Start();
        }

        private void StartProcess()
        {
            if (recoveryInstance != null)
                recoveryInstance.Start();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (processThread != null && processThread.IsAlive)
            {
                DialogResult result = MessageBox.Show("Are you sure you want to cancel this operation?", "PPI", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (result == System.Windows.Forms.DialogResult.Yes)
                {
                    processThread.Abort();
                    InitializeControls();
                }
            }

            Close();
        }

        private delegate void UpdateControls();

        private void recoveryInstance_DataBaseChanged(object sender, EventArgs e)
        {
            if (InvokeRequired)
                Invoke(new UpdateControls(UpdateDatabaseInfo));
            else
                UpdateDatabaseInfo();
        }

        private void recoveryInstance_ImageChanged(object sender, EventArgs e)
        {
            if (InvokeRequired)
                Invoke(new UpdateControls(UpdateImageFileInfo));
            else
                UpdateImageFileInfo();
        }

        private void recoveryInstance_ProcessFinished(object sender, EventArgs e)
        {
            if (InvokeRequired)
                Invoke(new UpdateControls(ShowFinishMessage));
            else
                ShowFinishMessage();            
        }

        #endregion

        #region - Private methods -

        private void SetupRecoveryInstance()
        {
            recoveryInstance = new LDistributionImageRecovery();
            recoveryInstance.DataBaseType = DatabaseTypes.DistributionInspection;            
            recoveryInstance.DataBaseChanged += recoveryInstance_DataBaseChanged;
            recoveryInstance.ImageChanged += recoveryInstance_ImageChanged;
            recoveryInstance.ProcessFinished += recoveryInstance_ProcessFinished;
            recoveryInstance.UploadError += recoveryInstance_UploadError;
        }

        private void recoveryInstance_UploadError(UploadingExceptionEventArg errorEventArgs)
        {
            var message = new StringBuilder();
            message.AppendLine(errorEventArgs.Message);
            message.AppendLine(); message.AppendLine();
            message.AppendLine("Exception message: " + errorEventArgs.Exception.Message);
            
            MessageBox.Show(message.ToString(), "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void UpdateDatabaseInfo()
        {
            lblDatabase.Text = recoveryInstance.ActualDataBaseName;
            pbDataBase.Value = recoveryInstance.ActualNumberOfDataBase;
            pbImage.Maximum = recoveryInstance.TotalOfImagesInDataBase;
            pbImage.Value = 0;
        }

        private void UpdateImageFileInfo()
        {
            lblImage.Text = recoveryInstance.ActualImageFileName;
            pbImage.Value = recoveryInstance.ActualNumberOfImage;
        }

        private void ShowFinishMessage()
        {
            MessageBox.Show("Finish");
            InitializeControls();
        }

        private void InitializeControls()
        {
            btnStart.Enabled = true;
            lblDatabase.Text = "-";
            lblImage.Text = "-";
            pbImage.Value = 0;
            pbDataBase.Value = 0;

            foreach (ListViewItem fileSelected in lvMobileFiles.CheckedItems)
                fileSelected.Checked = false;
        }

        private void LoadMobileDatabaseFiles()
        {
            var distributionSentFilesDirectory = new DirectoryInfo(Constants.K_SENTDISTRIBUTIONINSPECTIONFOLDERS);
            var subDirectories = distributionSentFilesDirectory.GetDirectories();
            var arrayFiles = new ArrayList();

            foreach (DirectoryInfo subDirectory in subDirectories)
                arrayFiles.AddRange(subDirectory.GetFiles());

            arrayFiles.Sort(new FileDateComparer());
            foreach (FileInfo file in arrayFiles)
            {
                var lvFile = new ListViewItem(string.Empty);

                lvFile.Tag = file;
                lvFile.SubItems.Add(file.Name);
                lvFile.SubItems.Add(file.CreationTime.ToShortDateString());

                lvMobileFiles.Items.Add(lvFile);
            }
        }
        #endregion
    }

    internal class FileDateComparer : IComparer
    {
        public int Compare(object x, object y)
        {
            return ((FileInfo)y).CreationTime.CompareTo(((FileInfo)x).CreationTime);
        }
    }
}
